package com.zwd.deep.utils;


import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.zwd.deep.common.ResultEnum;
import com.zwd.deep.handle.exception.GlobalException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Enumeration;
import java.util.Map;
import java.util.Objects;

/**
 * HttpServlet工具类
 *
 * @author wanjunhong
 */
@Component
public class HttpServletUtil {

    private static String tokenStr;

    @Value("${token.str}")
    public void setTokenStr(String tokenStr) {
        HttpServletUtil.tokenStr = tokenStr;
    }

    private final static String FINGERPRINT = "fingerprint";

    /**
     * 跨域请求头
     *
     */
    private static final String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";


    /**
     * 设置并暴露响应头
     *
     * @param headerMap: 响应头Map
     *                   key:响应头名称 value:响应头值
     * @author wanjunhong
     */
    public static void setResponseHeader(Map<String, String> headerMap) {
        //通过响应头返回token
        HttpServletResponse response = HttpServletUtil.getResponse();
        if (response == null) {
            throw new GlobalException(ResultEnum.SYSTEM_ERROR);
        }
        headerMap.forEach(response::setHeader);
        //拼接暴露头
        headerMap.keySet().stream().reduce((header1, header2) -> header1 + "," + header2)
                .ifPresent(headers -> response.setHeader(ACCESS_CONTROL_EXPOSE_HEADERS, headers));
    }

    /**
     * 获取HttpServletRequest
     *
     * @return HttpServletRequest
     * @author wanjunhong
     */
    public static HttpServletRequest getRequest() {
        try {
            ServletRequestAttributes attributes = getRequestAttributes();
            return attributes == null ? null : attributes.getRequest();
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 获取当前用户的ip地址
     *
     * @author wanjunhong
     */

    public static String getIp() {
        HttpServletRequest request = getRequest();
        if (Objects.isNull(request)) {
            return null;
        }
        return request.getRemoteAddr();
    }

    /**
     * 获取用户的浏览器指纹
     *
     * @author wanjunhong
     */
    public static String getBrowserFingerprint() {
        HttpServletRequest request = getRequest();
        if (request == null) {
            return null;
        }
        String fingerprint = request.getHeader(FINGERPRINT);
        if(StrUtil.isBlank(fingerprint)) {
            throw new GlobalException(ResultEnum.GET_USER_FINGERPRINT_ERROR);
        }
        return fingerprint;
    }

    /**
     * 获取HttpServletRequest的Cookie数组
     *
     * @return Cookie
     * @author wanjunhong
     */
    public static Cookie[] getCookies() {
        HttpServletRequest request = getRequest();
        if (request == null) {
            return null;
        }
        Cookie[] cookies = request.getCookies();
        return ArrayUtil.isEmpty(cookies) ? null : cookies;
    }

    /**
     * 根据Cookie名称获取Cookie值
     *
     * @param name: Cookie名称
     * @return String
     * @author wanjunhong
     */
    public static String getCookieValue(String name) {
        Cookie[] cookies = getCookies();
        if (ArrayUtil.isEmpty(cookies)) {
            return null;
        }
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(name)) {
                return cookie.getValue();
            }
        }
        return null;
    }

    /**
     * 获取Token值
     *
     * @return String
     * @author wanjunhong
     */
    public static String getToken() {
        HttpServletRequest request = getRequest();
        if (Objects.isNull(request)) {
            return null;
        }
        Enumeration<String> headerNames = request.getHeaderNames();
        return request.getHeader(tokenStr);
    }

    /**
     * 获取HttpServletResponse
     *
     * @return HttpServletResponse
     * @author wanjunhong
     */
    public static HttpServletResponse getResponse() {
        ServletRequestAttributes attributes = getRequestAttributes();
        return attributes == null ? null : attributes.getResponse();
    }

    /**
     * 获取RequestAttributes
     *
     * @return ServletRequestAttributes
     * @author wanjunhong
     */
    public static ServletRequestAttributes getRequestAttributes() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes() == null ? RequestContextHolder.currentRequestAttributes() : RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return null;
        } else {
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) attributes;

            try {
                RequestContextHolder.setRequestAttributes(servletRequestAttributes, true);
            } catch (Exception ignored) {

            }
            return servletRequestAttributes;
        }
    }

    /**
     * 获取请求url
     *
     * @return String
     * @author wanjunhong
     */
    public static String getRequestUrl() {
        HttpServletRequest request = getRequest();
        if (Objects.isNull(request)) {
            return null;
        }
        return request.getRequestURL().toString();
    }
}
